package club.zhilin.guli.service.trade.service.impl;

import club.zhilin.guli.common.base.result.CommonResultCodeEnum;
import club.zhilin.guli.common.base.util.HttpClientUtils;
import club.zhilin.guli.service.base.constant.GlobalConstant;
import club.zhilin.guli.service.base.exception.GlobalException;
import club.zhilin.guli.service.trade.domain.Order;
import club.zhilin.guli.service.trade.prop.WeiXinPayProperties;
import club.zhilin.guli.service.trade.service.IOrderService;
import club.zhilin.guli.service.trade.service.IWeiXinPayService;
import com.github.wxpay.sdk.WXPayUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

/**
 * @author zhilin
 * @since 2022/3/4 16:09
 */
@Slf4j
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@EnableConfigurationProperties({WeiXinPayProperties.class})
public class IWeiXinPayServiceImpl implements IWeiXinPayService {

    private final IOrderService iOrderService;
    private final WeiXinPayProperties weiXinPayProperties;

    @Override
    @SuppressWarnings({"all"})
    public Map<String, Object> createNative(String orderNo, String remoteAddr) {
        try {
            // 根据订单号获取订单
            Order order = iOrderService.getOrderByOrderNo(orderNo);
            // 调用微信的统一下单api
            HttpClientUtils client = new HttpClientUtils("https://api.mch.weixin.qq.com/pay/unifiedorder");
            // 组装参数
            Map<String, String> params = new HashMap<>(9);
            params.put("appid", weiXinPayProperties.getAppId());
            params.put("mch_id", weiXinPayProperties.getPartner());
            params.put("nonce_str", WXPayUtil.generateNonceStr());
            params.put("body", order.getCourseTitle());
            params.put("out_trade_no", order.getOrderNo());
            params.put("total_fee", order.getTotalFee().intValue() + "");
            params.put("spbill_create_ip", remoteAddr);
            params.put("notify_url", weiXinPayProperties.getNotifyUrl());
            params.put("trade_type", "NATIVE");
            // 将参数转换为xml字符串,并且在字符串的最后追加计算的签名
            String xmlParams = WXPayUtil.generateSignedXml(params, weiXinPayProperties.getPartnerKey());
            // 将参数放入请求对象的方法体中
            client.setXmlParam(xmlParams);
            // 使用https协议传输
            client.setHttps(true);
            // 使用post方式发送请求
            client.post();
            // 得到响应
            String result = client.getContent();
            Map<String, String> resultMap = WXPayUtil.xmlToMap(result);
            if (GlobalConstant.FAIL.equals(resultMap.get("return_code")) || GlobalConstant.FAIL.equals(resultMap.get("result_code"))) {
                log.error("微信支付统一下单错误 - return_code:{},return_msg:{},result_code:{},err_code:{},err_code_des:{}", resultMap.get("return_code"), resultMap.get("return_msg"), resultMap.get("result_code"), resultMap.get("err_code"), resultMap.get("error_code_des"));
                throw new GlobalException(CommonResultCodeEnum.PAY_UNIFIED_ORDER_ERROR);
            }
            Map<String, Object> map = new HashMap<>();
            map.put("result_code", resultMap.get("result_code"));
            map.put("code_url", resultMap.get("code_url"));
            map.put("course_id", order.getCourseId());
            map.put("total_fee", order.getTotalFee());
            map.put("out_trade_no", orderNo);
            return map;
        } catch (Exception e) {
            log.error(ExceptionUtils.getMessage(e));
            throw new GlobalException(CommonResultCodeEnum.PAY_ORDER_QUERY_ERROR);
        }
    }
}
